﻿// ProcessMasterDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "ProcessMaster.h"
#include "ProcessMasterDlg.h"
#include "afxdialogex.h"
#include "LogSystem.h"
#include "resource.h"  // 添加对资源头文件的直接引用

#include <TlHelp32.h>
#include <Psapi.h>
#include <shellapi.h>

#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "Shell32.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// 列表控件窗口过程函数前向声明
LRESULT CALLBACK ListViewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CProcessMasterDlg 对话框



CProcessMasterDlg::CProcessMasterDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_PROCESSMASTER_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	
	// 初始化滚动状态变量
	m_bIsScrolling = FALSE;
	m_dwLastScrollTime = 0;
	m_pOldListProc = NULL;
	m_nScrollPos = 0;
}

void CProcessMasterDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CProcessMasterDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SIZE()
	ON_WM_GETMINMAXINFO()
	ON_WM_ERASEBKGND()
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_PROCESS_LIST, &CProcessMasterDlg::OnCustomDrawList)
	ON_NOTIFY(NM_CLICK, IDC_PROCESS_LIST, &CProcessMasterDlg::OnClickList)
	ON_WM_TIMER()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_MOUSEWHEEL()
	ON_WM_CLOSE()
	ON_NOTIFY_REFLECT(LVN_BEGINSCROLL, &CProcessMasterDlg::OnListScroll)
	ON_COMMAND(ID_HELP_ABOUT, &CProcessMasterDlg::OnHelpAbout)
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_POPUP_ENDPROCESS, &CProcessMasterDlg::OnEndProcess)
	ON_COMMAND(ID_POPUP_PROCESSDETAIL, &CProcessMasterDlg::OnProcessDetail)
END_MESSAGE_MAP()


// CProcessMasterDlg 消息处理程序

BOOL CProcessMasterDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//CString logFilePath = GetLogFilePath();
	
	// 初始化日志系统
	/*if (!CLogSystem::GetInstance().Init())
	{
		AfxMessageBox(_T("日志系统初始化失败！"));
		return FALSE;
	}*/
	
	// 记录应用程序启动日志
	TRACE("ProcessMaster应用程序启动\n");

	// 将"关于..."菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// 设置窗口样式和外观
	SetupWindowStyle();

	// 加载菜单
    CMenu menu;
    menu.LoadMenu(IDR_MAIN_MENU);
    SetMenu(&menu);
    menu.Detach();

	// TODO: 在此添加额外的初始化代码
	
	// 动态创建所有控件（列表控件）
	CreateControls();

	// 尝试提升进程权限
	if (!EnableDebugPrivilege())
	{
		TRACE("无法获取调试权限，某些系统进程可能无法访问\n");
		MessageBox(_T("无法获取调试权限，某些系统进程可能无法访问。\n请尝试以管理员身份运行程序。"), _T("警告"), MB_OK | MB_ICONWARNING);
	}
	else
	{
		TRACE("成功获取调试权限，可以访问更多系统进程\n");
	}

	// 初始化进程列表
	InitProcessLists();

	// 刷新进程列表
	RefreshProcessLists();

	// 加载背景图片
	LoadBackgroundImage(IDB_BACKGROUND);

	// 启动定时器，设置为2秒刷新一次，减少频繁刷新带来的闪烁
	SetTimer(1, 2000, NULL);

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CProcessMasterDlg::SetupWindowStyle()
{
    // 添加最大化和最小化按钮，并允许调整大小
    DWORD dwStyle = GetStyle();
    DWORD dwExStyle = GetExStyle();
    dwStyle |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_THICKFRAME;
    dwExStyle |= WS_EX_DLGMODALFRAME;
    
    // 必须先移除对话框边框，再重新设置样式
    ModifyStyle(WS_CAPTION, 0);
    SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
    SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle);
    
    // 重新添加标题栏
    ModifyStyle(0, WS_CAPTION);
    
    // 强制重绘非客户区域，使样式更改生效
    SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    
    // 设置窗口初始大小 - 调整为更大的尺寸
    SetWindowPos(NULL, 0, 0, 1024, 768, SWP_NOMOVE | SWP_NOZORDER);
    
    // 设置窗口标题和菜单
    SetWindowText(_T("任务管理器"));
}

void CProcessMasterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CProcessMasterDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CProcessMasterDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

/*
函数：CreateControls
功能：动态创建所有控件
说明：该功能在对话框初始化的时候调用，负责创建所有UI控件
*/
void CProcessMasterDlg::CreateControls()
{
	// 获取对话框客户区的大小
	CRect clientRect;
	GetClientRect(&clientRect);

	// 设置控件的位置和大小
	const int margin = 10;

	// 计算列表控件的位置和大小 - 现在占据整个对话框空间（移除了按钮区域）
	int listWidth = clientRect.Width() - 2 * margin;
	int listHeight = clientRect.Height() - 2 * margin; // 移除了按钮的高度

	// 创建列表控件
	m_processList.Create(
		WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS,
		CRect(margin, margin, margin + listWidth, margin + listHeight),
		this,
		IDC_PROCESS_LIST);

	// 美化列表控件
	// 设置列表控件扩展样式
	DWORD dwExStyle = m_processList.GetExtendedStyle();
	dwExStyle |= LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER; // 移除 LVS_EX_GRIDLINES
	m_processList.SetExtendedStyle(dwExStyle);
	
	// 设置列表控件背景为半透明
	m_processList.SetBkColor(RGB(240, 240, 240)); // 浅灰色背景
	m_processList.SetTextBkColor(RGB(240, 240, 240)); // 文本背景与列表背景一致
	m_processList.SetTextColor(RGB(0, 0, 0)); // 黑色文本，更容易看清
	
	// 创建并设置自定义字体
	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	lf.lfHeight = 16; // 字体大小
	lf.lfWeight = FW_NORMAL; // 字体粗细
	_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("微软雅黑")); // 字体名称
	
	if (m_fontList.m_hObject != NULL)
		m_fontList.DeleteObject();
	
	m_fontList.CreateFontIndirect(&lf);
	m_processList.SetFont(&m_fontList);
	
	// 设置行高
	CImageList imgList;
	imgList.Create(1, 32, ILC_COLOR, 1, 1); // 32像素的行高
	m_processList.SetImageList(&imgList, LVSIL_SMALL);
	imgList.Detach();

	// 初始化当前选中项为-1
	m_nCurrentItem = -1;
	
	// 为列表控件设置窗口过程子类化，以捕获滚动消息
	HWND hListWnd = m_processList.GetSafeHwnd();
	if (hListWnd)
	{
		// 保存原始窗口过程
		m_pOldListProc = (WNDPROC)SetWindowLongPtr(hListWnd, GWLP_WNDPROC, (LONG_PTR)ListViewProc);
		// 保存对话框指针到窗口用户数据中
		SetWindowLongPtr(hListWnd, GWLP_USERDATA, (LONG_PTR)this);
		
		// 初始化滚动相关变量
		m_bIsScrolling = FALSE;
		m_dwLastScrollTime = 0;
	}
}

/*
函数：InitProcessLists
功能：初始化进程列表控件
说明：添加列标题和设置列宽，在CreateControls函数之后调用
*/
void CProcessMasterDlg::InitProcessLists()
{
    // 初始化列表控件
    InitProcessListControl(m_processList);

    // 设置列表控件字体
    LOGFONT lf;
    memset(&lf, 0, sizeof(LOGFONT));
    lf.lfHeight = 16;
    lf.lfWeight = FW_NORMAL;
    _tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("微软雅黑"));
    
    if (m_fontList.m_hObject != NULL)
        m_fontList.DeleteObject();

    m_fontList.CreateFontIndirect(&lf);
    m_processList.SetFont(&m_fontList);

    // 设置列表控件项目高度
    // 通过设置图像列表的高度来间接设置行高
    m_nItemHeight = 32;
    CImageList imgList;
    imgList.Create(1, m_nItemHeight, ILC_COLOR, 1, 1);
    
    m_processList.SetImageList(&imgList, LVSIL_STATE);
    imgList.Detach();
    
    // 创建一个更高的图像列表用于分组标题
    CImageList imgListGroup;
    imgListGroup.Create(1, m_nItemHeight + 16, ILC_COLOR, 1, 1); // 分组标题行比普通行高16像素
    
    m_processList.SetImageList(&imgListGroup, LVSIL_GROUPHEADER);
    imgListGroup.Detach();

    // 删除重复的窗口过程子类化代码
    // 注释：这部分代码在CreateControls函数中已经执行过
    // 重复执行会导致堆栈溢出
}

/*
函数：InitProcessListControl
功能：初始化单个进程列表控件
参数：listCtrl - 列表控件引用
说明：设置列表控件的样式和列标题
*/
void CProcessMasterDlg::InitProcessListControl(CListCtrl& listCtrl)
{
    // 设置列表控件样式
    DWORD dwStyle = listCtrl.GetExtendedStyle();
    dwStyle |= LVS_EX_FULLROWSELECT;    // 整行选择
    // dwStyle |= LVS_EX_GRIDLINES;        // 不显示网格线（移除竖线分隔符）
    dwStyle |= LVS_EX_DOUBLEBUFFER;     // 双缓冲（减少闪烁）
    listCtrl.SetExtendedStyle(dwStyle);

    // 添加列标题
    listCtrl.InsertColumn(0, _T("名称"), LVCFMT_LEFT, 220);
    listCtrl.InsertColumn(1, _T("PID"), LVCFMT_RIGHT, 80);
    listCtrl.InsertColumn(2, _T("CPU"), LVCFMT_RIGHT, 80);
    listCtrl.InsertColumn(3, _T("内存"), LVCFMT_RIGHT, 120);
    listCtrl.InsertColumn(4, _T("线程数"), LVCFMT_RIGHT, 80);
}

/*
函数：RefreshProcessLists
功能：刷新进程列表数据
说明：获取系统中所有进程信息并显示在列表中
*/
void CProcessMasterDlg::RefreshProcessLists()
{
	TRACE("开始刷新进程列表\n");

	// 第1步: 准备工作
	//----------------------------------------------
	// 更新所有进程的CPU使用率信息
	UpdateAllProcessCPUUsage();

	// 保存当前选中的进程ID
	DWORD selectedProcessID = GetSelectedProcessID();
	int selectedItemIndex = -1;
	
	// 禁用窗口更新，减少闪烁
	m_processList.SetRedraw(FALSE);
	
	// 完全重建图像列表
	if (m_imageList.m_hImageList != NULL)
	{
		m_imageList.DeleteImageList();
	}
	
	// 创建新的图像列表
	m_imageList.Create(32, 32, ILC_COLOR32 | ILC_MASK, 100, 20);
	
	// 不添加占位符图标，让每个进程都使用自己的图标
	
	// 设置图像列表
	m_processList.SetImageList(&m_imageList, LVSIL_SMALL);
	
	// 清空列表
	m_processList.DeleteAllItems();

	// 第2步: 创建进程分类容器
	//----------------------------------------------
	// 创建三个列表，分别存储不同类型的进程信息
	CArray<ProcessInfo, ProcessInfo&> appProcesses;     // 应用进程
	CArray<ProcessInfo, ProcessInfo&> backgroundProcesses; // 后台进程
	CArray<ProcessInfo, ProcessInfo&> windowsProcesses;  // Windows系统进程

	// 第3步: 获取进程信息
	//----------------------------------------------
	// 创建进程快照
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapshot == INVALID_HANDLE_VALUE)
	{
		TRACE("创建进程快照失败，错误码: %d\n", GetLastError());
		return;
	}
	
	// 遍历所有进程，按类型分类
	PROCESSENTRY32 pe32 = { 0 };
	pe32.dwSize = sizeof(PROCESSENTRY32);

	// 获取第一个进程信息
	if (!Process32First(hSnapshot, &pe32))
	{
		TRACE("获取第一个进程信息失败，错误码: %d\n", GetLastError());
		CloseHandle(hSnapshot);
		return;
	}
	
	// 第4步: 遍历进程并分类
	//----------------------------------------------
	int index = 0;
	do
	{
		// 收集进程信息
		ProcessInfo processInfo = CollectProcessInfo(pe32, selectedProcessID, selectedItemIndex);
		
		// 根据进程类型添加到对应的列表
		switch (processInfo.type)
		{
		case PROCESS_TYPE_APP:
			appProcesses.Add(processInfo);
			break;
		case PROCESS_TYPE_BACKGROUND:
			backgroundProcesses.Add(processInfo);
			break;
		case PROCESS_TYPE_WINDOWS:
			windowsProcesses.Add(processInfo);
			break;
		}
		
	} while (Process32Next(hSnapshot, &pe32));

	// 关闭进程快照
	CloseHandle(hSnapshot);
	
	// 第5步: 按类型顺序显示进程
	//----------------------------------------------
	// 显示应用进程组
	if (appProcesses.GetSize() > 0)
	{
		// 添加应用进程组标题
		LVITEM lvi = {0};
		lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
		lvi.iItem = index++;
		lvi.iSubItem = 0;
		lvi.pszText = _T("应用进程 (Apps)");
		lvi.lParam = GROUP_HEADER_APP; // 使用特殊标识符标记为组标题
		lvi.iImage = -1; // 不显示图标
		
		int nItem = m_processList.InsertItem(&lvi);
		m_processList.SetItemText(nItem, 1, _T(""));
		m_processList.SetItemText(nItem, 2, _T(""));
		m_processList.SetItemText(nItem, 3, _T(""));
		m_processList.SetItemText(nItem, 4, _T(""));
		
		// 添加应用进程 (显示在最前面)
		for (int i = 0; i < appProcesses.GetSize(); i++)
		{
			AddProcessToList(m_processList, appProcesses[i], index++, selectedProcessID, selectedItemIndex);
		}
	}
	
	// 显示后台进程组
	if (backgroundProcesses.GetSize() > 0)
	{
		// 添加后台进程组标题
		LVITEM lvi = {0};
		lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
		lvi.iItem = index++;
		lvi.iSubItem = 0;
		lvi.pszText = _T("后台进程 (Background)");
		lvi.lParam = GROUP_HEADER_BACKGROUND; // 使用特殊标识符标记为组标题
		lvi.iImage = -1; // 不显示图标
		
		int nItem = m_processList.InsertItem(&lvi);
		m_processList.SetItemText(nItem, 1, _T(""));
		m_processList.SetItemText(nItem, 2, _T(""));
		m_processList.SetItemText(nItem, 3, _T(""));
		m_processList.SetItemText(nItem, 4, _T(""));
		
		// 添加后台进程 (显示在中间)
		for (int i = 0; i < backgroundProcesses.GetSize(); i++)
		{
			AddProcessToList(m_processList, backgroundProcesses[i], index++, selectedProcessID, selectedItemIndex);
		}
	}
	
	// 显示Windows进程组
	if (windowsProcesses.GetSize() > 0)
	{
		// 添加Windows进程组标题
		LVITEM lvi = {0};
		lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
		lvi.iItem = index++;
		lvi.iSubItem = 0;
		lvi.pszText = _T("系统进程 (System)");
		lvi.lParam = GROUP_HEADER_WINDOWS; // 使用特殊标识符标记为组标题
		lvi.iImage = -1; // 不显示图标
		
		int nItem = m_processList.InsertItem(&lvi);
		m_processList.SetItemText(nItem, 1, _T(""));
		m_processList.SetItemText(nItem, 2, _T(""));
		m_processList.SetItemText(nItem, 3, _T(""));
		m_processList.SetItemText(nItem, 4, _T(""));
		
		// 添加Windows进程 (显示在最后)
		for (int i = 0; i < windowsProcesses.GetSize(); i++)
		{
			AddProcessToList(m_processList, windowsProcesses[i], index++, selectedProcessID, selectedItemIndex);
		}
	}

	// 第6步: 恢复UI状态
	//----------------------------------------------
	// 恢复选中状态
	if (selectedItemIndex != -1)
	{
		m_processList.SetItemState(selectedItemIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		m_processList.EnsureVisible(selectedItemIndex, FALSE);
	}
	
	// 恢复滚动位置
	if (m_nScrollPos > 0 && m_nScrollPos < m_processList.GetItemCount())
	{
		// 使用更可靠的方法恢复滚动位置
		m_processList.SetRedraw(TRUE); // 临时启用重绘以便滚动
		m_processList.EnsureVisible(m_nScrollPos, FALSE);
		
		// 使用PostMessage发送滚动消息，确保在UI线程上执行
		m_processList.SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_nScrollPos), 0);
		
		TRACE("恢复滚动位置: %d\n", m_nScrollPos);
		m_processList.SetRedraw(FALSE); // 再次禁用重绘完成剩余操作
	}
	
	// 重新启用窗口更新
	m_processList.SetRedraw(TRUE);

	// 记录完成刷新进程列表
	TRACE("完成刷新进程列表，共 %d 个进程\n", m_processList.GetItemCount());
}

/*
函数：CollectProcessInfo
功能：收集单个进程的详细信息
参数： 
	pe32 - 进程基本信息
	selectedProcessID - 当前选中的进程ID
	selectedItemIndex - 选中项索引的引用，如果找到选中项会更新此值
返回值： 
	进程详细信息结构体
*/
ProcessInfo CProcessMasterDlg::CollectProcessInfo(const PROCESSENTRY32& pe32, 
                                                DWORD selectedProcessID, 
                                                int& selectedItemIndex)
{
	// 检查是否是当前选中的进程
	if (pe32.th32ProcessID == selectedProcessID)
	{
		// 记录当前选中项的索引，稍后会重新选中
		selectedItemIndex = 0; // 暂时设为0，后面会更新
	}

	// 创建进程信息结构
	ProcessInfo processInfo;
	ZeroMemory(&processInfo, sizeof(ProcessInfo));
	memcpy(&processInfo.pe32, &pe32, sizeof(PROCESSENTRY32));
	
	// 获取进程路径和图标
	processInfo.szProcessPath[0] = _T('\0');
	processInfo.iconIndex = -1;
	processInfo.hIcon = NULL;
	
	// 打开进程获取完整路径
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
	if (hProcess)
	{
		// 获取进程路径
		if (GetModuleFileNameEx(hProcess, NULL, processInfo.szProcessPath, MAX_PATH))
		{
			// 获取进程图标并添加到图像列表
			processInfo.iconIndex = this->GetProcessIcon(processInfo.szProcessPath, processInfo.hIcon);
		}
		
		// 获取进程内存使用
		PROCESS_MEMORY_COUNTERS pmc;
		ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS));
		pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
		
		if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
		{
			processInfo.memoryUsage = pmc.WorkingSetSize;
		}
		
		CloseHandle(hProcess);
	}
	
	// 如果无法获取图标，使用默认图标
	if (processInfo.iconIndex == -1)
	{
		HICON hDefaultIcon = (HICON)LoadImage(AfxGetInstanceHandle(), 
							MAKEINTRESOURCE(IDI_APPLICATION),
							IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
		if (hDefaultIcon)
		{
			processInfo.iconIndex = m_imageList.Add(hDefaultIcon);
			DestroyIcon(hDefaultIcon);
		}
	}
	
	// 获取CPU使用率
	processInfo.cpuUsage = 0.0;
	PROCESS_CPU_INFO cpuInfo;
	if (m_ProcessCPUInfo.Lookup(pe32.th32ProcessID, cpuInfo))
	{
		processInfo.cpuUsage = cpuInfo.cpuUsage;
	}
	
	// 获取进程类型
	processInfo.type = this->GetProcessType(processInfo.szProcessPath, pe32.szExeFile);
	
	return processInfo;
}

/*
函数：AddProcessToList
功能：将进程信息添加到列表控件中
参数：
	listCtrl - 列表控件引用
	processInfo - 进程信息结构体
	index - 在列表中的索引
	selectedProcessID - 当前选中的进程ID
	selectedItemIndex - 选中项的索引引用
*/
void CProcessMasterDlg::AddProcessToList(CListCtrl& listCtrl, const ProcessInfo& processInfo, int index, 
                                        DWORD selectedProcessID, int& selectedItemIndex)
{
	// 添加进程到列表
	LVITEM lvi = {0};
	lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
	lvi.iItem = index;
	lvi.iSubItem = 0;
	
	// 设置图标索引
	if (processInfo.iconIndex >= 0)
	{
		lvi.iImage = processInfo.iconIndex;
	}
	
	// 设置进程名称和进程ID作为项数据
	lvi.pszText = (LPTSTR)processInfo.pe32.szExeFile;
	lvi.lParam = (LPARAM)processInfo.pe32.th32ProcessID;
	
	int nItem = listCtrl.InsertItem(&lvi);
	
	// 添加进程ID
	CString strPID;
	strPID.Format(_T("%u"), processInfo.pe32.th32ProcessID);
	listCtrl.SetItemText(nItem, 1, strPID);
	
	// 添加CPU使用率
	CString strCPU;
	strCPU.Format(_T("%.1f%%"), processInfo.cpuUsage);
	listCtrl.SetItemText(nItem, 2, strCPU);
	
	// 添加内存使用
	CString strMemory;
	if (processInfo.memoryUsage < 1024 * 1024)
	{
		// 小于1MB，显示KB
		strMemory.Format(_T("%.0f KB"), processInfo.memoryUsage / 1024.0);
	}
	else if (processInfo.memoryUsage < 1024 * 1024 * 1024)
	{
		// 小于1GB，显示MB
		strMemory.Format(_T("%.1f MB"), processInfo.memoryUsage / (1024.0 * 1024.0));
	}
	else
	{
		// 大于等于1GB，显示GB
		strMemory.Format(_T("%.2f GB"), processInfo.memoryUsage / (1024.0 * 1024.0 * 1024.0));
	}
	listCtrl.SetItemText(nItem, 3, strMemory);
	
	// 添加线程数
	CString strThreads;
	strThreads.Format(_T("%d"), processInfo.pe32.cntThreads);
	listCtrl.SetItemText(nItem, 4, strThreads);
	
	// 如果是当前选中的进程，保存其索引
	if (processInfo.pe32.th32ProcessID == selectedProcessID)
	{
		selectedItemIndex = nItem;
	}
}

/*
函数：OnSize
功能：处理窗口大小改变事件
参数：
	nType - 大小改变类型（最大化、最小化等）
	cx - 新的宽度
	cy - 新的高度
说明：当窗口大小改变时，重新调整控件大小和位置，保持界面布局美观
*/
void CProcessMasterDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// 如果窗口最小化，不需要调整控件
	if (nType == SIZE_MINIMIZED)
		return;

	// 如果控件尚未创建，不需要调整
	if (!::IsWindow(m_processList.GetSafeHwnd()))
		return;

	// 获取客户区矩形
	CRect clientRect;
	GetClientRect(&clientRect);

	// 计算控件新位置和大小
	const int margin = 10;  // 边距

	// 调整进程列表大小
	int listWidth = clientRect.Width() - 2 * margin;
	int listHeight = clientRect.Height() - 2 * margin;

	// 调整进程列表
	m_processList.MoveWindow(margin, margin, listWidth, margin + listHeight);

	// 重绘控件
	Invalidate();
	UpdateWindow();

	// 记录窗口大小调整日志
	TRACE("窗口大小已调整为 %d x %d\n", cx, cy);
}

/*
函数：OnGetMinMaxInfo
功能：处理窗口最小/最大化事件
参数：
	lpMMI - 最小/最大化信息结构体
*/
void CProcessMasterDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
    // TODO: 在此添加消息处理程序代码
    CDialogEx::OnGetMinMaxInfo(lpMMI);
    lpMMI->ptMinTrackSize.x = 1024;
    lpMMI->ptMinTrackSize.y = 768;
}

BOOL CProcessMasterDlg::OnEraseBkgnd(CDC* pDC)
{
    // 绘制背景图片
    if (m_bmpBackground.m_hObject != NULL)
    {
        CRect rect;
        GetClientRect(&rect);
        
        CDC dcMem;
        dcMem.CreateCompatibleDC(pDC);
        CBitmap* pOldBitmap = dcMem.SelectObject(&m_bmpBackground);
        
        BITMAP bm;
        m_bmpBackground.GetBitmap(&bm);
        
        // 拉伸绘制背景图片以适应窗口大小
        pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), 
                      &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
        
        dcMem.SelectObject(pOldBitmap);
        
        // 设置列表控件为透明
        if (::IsWindow(m_processList.GetSafeHwnd()))
        {
            // 使列表控件透明
            m_processList.SetBkColor(CLR_NONE);
            m_processList.SetTextBkColor(CLR_NONE);
        }
        
        return TRUE;
    }
    
    // 如果没有背景图片，则使用默认的白色背景
    CRect rect;
    GetClientRect(&rect);
    CBrush brush(RGB(240, 240, 240));
    pDC->FillRect(&rect, &brush);
    return TRUE;
}

BOOL CProcessMasterDlg::LoadBackgroundImage(UINT nResourceID)
{
    // 清除旧的背景图片
    if (m_bmpBackground.m_hObject != NULL)
    {
        m_bmpBackground.DeleteObject();
    }
    
    // 从资源加载背景图片
    BOOL result = m_bmpBackground.LoadBitmap(nResourceID);
    if (!result)
    {
        TRACE("加载背景图片失败\n");
        return FALSE;
    }
    
    TRACE("成功加载背景图片\n");
    
    // 强制重绘窗口，使背景图片立即显示
    Invalidate();
    UpdateWindow();
    
    return TRUE;
}

void CProcessMasterDlg::OnHelpAbout()
{
    CAboutDlg aboutDlg;
    aboutDlg.DoModal();
}

void CProcessMasterDlg::OnClickList(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    
    // 更新当前选中的列表和项
    m_nCurrentItem = pNMItemActivate->iItem;
    
    *pResult = 0;
}

void CProcessMasterDlg::OnTimer(UINT_PTR nIDEvent)
{
    // 检查用户是否正在滚动
    if (m_bIsScrolling)
    {
        // 获取当前时间
        DWORD dwCurrentTime = GetTickCount();
        
        // 计算自上次滚动以来经过的时间（毫秒）
        DWORD dwElapsedTime = dwCurrentTime - m_dwLastScrollTime;
        
        // 如果超过3秒没有滚动，认为用户已停止滚动
        if (dwElapsedTime > 3000)
        {
            TRACE("用户停止滚动，恢复自动刷新\n");
            m_bIsScrolling = FALSE;
        }
        else
        {
            // 用户仍在滚动，跳过本次刷新
            TRACE("用户正在滚动，暂停刷新 (经过时间: %d ms)\n", dwElapsedTime);
            CDialogEx::OnTimer(nIDEvent);
            return;
        }
    }
    
    // 用户没有在滚动，刷新进程列表
    RefreshProcessLists();
    CDialogEx::OnTimer(nIDEvent);
}

void CProcessMasterDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // 记录用户正在滚动
    m_bIsScrolling = TRUE;
    m_dwLastScrollTime = GetTickCount();
    
    // 保存滚动位置
    if (m_processList.GetItemCount() > 0)
    {
        m_nScrollPos = m_processList.GetTopIndex();
        TRACE("OnVScroll保存滚动位置: %d\n", m_nScrollPos);
    }
    
    TRACE("检测到垂直滚动，暂停自动刷新\n");
    
    CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CProcessMasterDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // 记录用户正在滚动
    m_bIsScrolling = TRUE;
    m_dwLastScrollTime = GetTickCount();
    
    TRACE("检测到水平滚动，暂停自动刷新\n");
    
    CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CProcessMasterDlg::OnListScroll(NMHDR* pNMHDR, LRESULT* pResult)
{
    // 记录用户正在滚动
    m_bIsScrolling = TRUE;
    m_dwLastScrollTime = GetTickCount();
    
    TRACE("检测到列表控件滚动，暂停自动刷新\n");
    
    *pResult = 0;
}

BOOL CProcessMasterDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    // 记录用户正在滚动
    m_bIsScrolling = TRUE;
    m_dwLastScrollTime = GetTickCount();
    
    // 保存滚动位置
    if (m_processList.GetItemCount() > 0)
    {
        m_nScrollPos = m_processList.GetTopIndex();
        TRACE("OnMouseWheel保存滚动位置: %d\n", m_nScrollPos);
    }
    
    TRACE("检测到鼠标滚轮滚动，暂停自动刷新\n");
    
    return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}

// 列表控件窗口过程函数，用于捕获滚动消息
LRESULT CALLBACK ListViewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // 获取对话框指针
    CProcessMasterDlg* pDlg = (CProcessMasterDlg*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    if (!pDlg)
    {
        // 如果没有对话框指针，调用原始窗口过程
        return ::DefWindowProc(hWnd, message, wParam, lParam);
    }

    // 捕获滚动消息
    switch (message)
    {
    case WM_VSCROLL:
        // 记录用户正在滚动
        pDlg->m_bIsScrolling = TRUE;
        pDlg->m_dwLastScrollTime = GetTickCount();
        
        // 保存滚动位置
        if (pDlg->m_processList.GetItemCount() > 0)
        {
            // 获取当前第一个可见项的索引
            pDlg->m_nScrollPos = pDlg->m_processList.GetTopIndex();
            TRACE("保存滚动位置: %d\n", pDlg->m_nScrollPos);
        }
        
        TRACE("列表控件窗口过程捕获到垂直滚动消息\n");
        break;
        
    case WM_HSCROLL:
    case WM_MOUSEWHEEL:
        // 记录用户正在滚动
        pDlg->m_bIsScrolling = TRUE;
        pDlg->m_dwLastScrollTime = GetTickCount();
        
        // 对于鼠标滚轮，也需要保存滚动位置
        if (message == WM_MOUSEWHEEL && pDlg->m_processList.GetItemCount() > 0)
        {
            pDlg->m_nScrollPos = pDlg->m_processList.GetTopIndex();
            TRACE("保存滚动位置(鼠标滚轮): %d\n", pDlg->m_nScrollPos);
        }
        
        TRACE("列表控件窗口过程捕获到滚动消息: %d\n", message);
        break;
    }

    // 调用原始窗口过程 - 添加安全检查
    if (pDlg->m_pOldListProc)
    {
        return ::CallWindowProc(pDlg->m_pOldListProc, hWnd, message, wParam, lParam);
    }
    else
    {
        // 原始窗口过程无效，使用默认处理
        TRACE("警告: m_pOldListProc为空，使用默认窗口过程\n");
        return ::DefWindowProc(hWnd, message, wParam, lParam);
    }
}

/*
函数：OnCustomDrawList
功能：通用自定义绘制函数
说明：为不同类型的进程设置不同的背景色
*/
void CProcessMasterDlg::OnCustomDrawList(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    *pResult = CDRF_DODEFAULT;

    if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
    {
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    {                                                               
        // 获取当前项的索引
        int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
        
        // 获取进程ID（存储在列表项的lParam中）
        DWORD processID = (DWORD)m_processList.GetItemData(nItem);
        
        // 获取进程类型
        ProcessType processType = PROCESS_TYPE_UNKNOWN;
        
        // 检查是否是分组标题行
        if (processID == GROUP_HEADER_APP)
        {
            // 应用进程组标题
            pLVCD->clrTextBk = RGB(180, 210, 255);  // 浅蓝色背景（更鲜明）
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
            
            // 创建粗体字体
            static HFONT hBoldFont = NULL;
            if (hBoldFont == NULL)
            {
                // 获取系统默认GUI字体
                LOGFONT lf;
                HFONT hDefaultFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
                GetObject(hDefaultFont, sizeof(LOGFONT), &lf);
                
                // 修改为粗体，并增大字体大小
                lf.lfWeight = FW_BOLD;
                lf.lfHeight = (lf.lfHeight * 3) / 2; // 增大字体大小约50%
                
                // 创建新字体
                hBoldFont = CreateFontIndirect(&lf);
            }
            
            // 应用粗体字体
            SelectObject(pLVCD->nmcd.hdc, hBoldFont);
            
            *pResult = CDRF_NEWFONT;
            return;
        }
        else if (processID == GROUP_HEADER_BACKGROUND)
        {
            // 后台进程组标题
            pLVCD->clrTextBk = RGB(180, 255, 180);  // 浅绿色背景（更鲜明）
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
            
            // 创建粗体字体
            static HFONT hBoldFont = NULL;
            if (hBoldFont == NULL)
            {
                // 获取系统默认GUI字体
                LOGFONT lf;
                HFONT hDefaultFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
                GetObject(hDefaultFont, sizeof(LOGFONT), &lf);
                
                // 修改为粗体，并增大字体大小
                lf.lfWeight = FW_BOLD;
                lf.lfHeight = (lf.lfHeight * 3) / 2; // 增大字体大小约50%
                
                // 创建新字体
                hBoldFont = CreateFontIndirect(&lf);
            }
            
            // 应用粗体字体
            SelectObject(pLVCD->nmcd.hdc, hBoldFont);
            
            *pResult = CDRF_NEWFONT;
            return;
        }
        else if (processID == GROUP_HEADER_WINDOWS)
        {
            // Windows进程组标题
            pLVCD->clrTextBk = RGB(210, 210, 210);  // 浅灰色背景（更鲜明）
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
            
            // 创建粗体字体
            static HFONT hBoldFont = NULL;
            if (hBoldFont == NULL)
            {
                // 获取系统默认GUI字体
                LOGFONT lf;
                HFONT hDefaultFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
                GetObject(hDefaultFont, sizeof(LOGFONT), &lf);
                
                // 修改为粗体，并增大字体大小
                lf.lfWeight = FW_BOLD;
                lf.lfHeight = (lf.lfHeight * 3) / 2; // 增大字体大小约50%
                
                // 创建新字体
                hBoldFont = CreateFontIndirect(&lf);
            }
            
            // 应用粗体字体
            SelectObject(pLVCD->nmcd.hdc, hBoldFont);
            
            *pResult = CDRF_NEWFONT;
            return;
        }
        else
        {
            // 普通进程项
            // 获取进程类型
            CString processName = m_processList.GetItemText(nItem, 0);
            
            // 根据进程名称前缀判断进程类型
            if (nItem > 0)
            {
                // 检查前面的项是否是分组标题
                DWORD prevItemData = (DWORD)m_processList.GetItemData(nItem - 1);
                if (prevItemData == GROUP_HEADER_APP)
                {
                    processType = PROCESS_TYPE_APP;
                }
                else if (prevItemData == GROUP_HEADER_BACKGROUND)
                {
                    processType = PROCESS_TYPE_BACKGROUND;
                }
                else if (prevItemData == GROUP_HEADER_WINDOWS)
                {
                    processType = PROCESS_TYPE_WINDOWS;
                }
                else
                {
                    // 检查当前项和前一项之间是否有分组标题
                    for (int i = nItem - 1; i >= 0; i--)
                    {
                        DWORD itemData = (DWORD)m_processList.GetItemData(i);
                        if (itemData == GROUP_HEADER_APP)
                        {
                            processType = PROCESS_TYPE_APP;
                            break;
                        }
                        else if (itemData == GROUP_HEADER_BACKGROUND)
                        {
                            processType = PROCESS_TYPE_BACKGROUND;
                            break;
                        }
                        else if (itemData == GROUP_HEADER_WINDOWS)
                        {
                            processType = PROCESS_TYPE_WINDOWS;
                            break;
                        }
                    }
                }
            }
            
            // 根据进程类型设置背景色
            if (processType == PROCESS_TYPE_APP)
            {
                // 应用进程
                pLVCD->clrTextBk = RGB(240, 245, 255);  // 浅蓝色背景
            }
            else if (processType == PROCESS_TYPE_BACKGROUND)
            {
                // 后台进程
                pLVCD->clrTextBk = RGB(240, 255, 240);  // 浅绿色背景
            }
            else if (processType == PROCESS_TYPE_WINDOWS)
            {
                // Windows进程
                pLVCD->clrTextBk = RGB(245, 245, 245);  // 浅灰色背景
            }
            else
            {
                // 未知类型
                pLVCD->clrTextBk = RGB(255, 255, 255);  // 白色背景
            }
            
            // 设置文本颜色
            pLVCD->clrText = RGB(0, 0, 0);  // 黑色文本
        }
        
        // 选中项使用高亮效果
        if (m_processList.GetItemState(nItem, LVIS_SELECTED) & LVIS_SELECTED)
        {
            // 选中项使用蓝色背景
            pLVCD->clrTextBk = ::GetSysColor(COLOR_HIGHLIGHT);
            pLVCD->clrText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
        }
        
        *pResult = CDRF_NEWFONT;
    }
}

/*
函数：GetProcessIcon
功能：获取进程图标
参数： 
	szProcessPath - 进程可执行文件路径
	hIcon - 返回的图标句柄
返回值： 
	成功返回图像列表中的索引，失败返回-1
说明： 
	获取进程的图标并添加到图像列表中
*/
int CProcessMasterDlg::GetProcessIcon(LPCTSTR szProcessPath, HICON& hIcon)
{
    // 如果路径为空，返回-1
    if (szProcessPath == NULL || szProcessPath[0] == _T('\0'))
    {
        return -1;
    }
    
    // 从可执行文件中提取图标
    SHFILEINFO sfi = {0};
    DWORD_PTR result = SHGetFileInfo(szProcessPath, 0, &sfi, sizeof(SHFILEINFO), 
                                    SHGFI_ICON | SHGFI_LARGEICON); // 使用大图标
    
    // 如果获取失败，返回-1
    if (result == 0 || sfi.hIcon == NULL)
    {
        // 尝试使用默认图标
        hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), 
                               MAKEINTRESOURCE(IDI_APPLICATION),
                               IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
        
        if (hIcon == NULL)
        {
            return -1;
        }
        
        int iconIndex = m_imageList.Add(hIcon);
        return iconIndex;
    }
    
    // 将图标添加到图像列表
    int iconIndex = m_imageList.Add(sfi.hIcon);
    
    // 保存图标句柄以便调用者使用
    hIcon = sfi.hIcon;
    
    // 返回图标索引
    return iconIndex;
}

/*
函数：GetProcessType
功能：获取进程类型
参数： 
	szProcessPath - 进程可执行文件路径
	szExeFile - 进程可执行文件名
返回值： 
	进程类型枚举值
说明： 
	根据进程路径和名称判断进程类型
*/
ProcessType CProcessMasterDlg::GetProcessType(LPCTSTR szProcessPath, LPCTSTR szExeFile)
{
    // Windows系统进程的路径特征
    static const LPCTSTR windowsPaths[] = {
        _T("\\Windows\\System32\\"),
        _T("\\Windows\\SysWOW64\\"),
        _T("\\Windows\\"),
        _T("\\WinSxS\\"),
        _T("\\Windows\\SystemApps\\")
    };
    
    // 常见的Windows系统进程名称
    static const LPCTSTR windowsProcesses[] = {
        _T("svchost.exe"),
        _T("csrss.exe"),
        _T("smss.exe"),
        _T("services.exe"),
        _T("lsass.exe"),
        _T("winlogon.exe"),
        _T("explorer.exe"),
        _T("dwm.exe"),
        _T("wininit.exe"),
        _T("spoolsv.exe"),
        _T("taskmgr.exe"),
        _T("conhost.exe"),
        _T("rundll32.exe"),
        _T("dllhost.exe"),
        _T("taskhost.exe"),
        _T("taskhostw.exe"),
        _T("ctfmon.exe"),
        _T("fontdrvhost.exe"),
        _T("sihost.exe"),
        _T("RuntimeBroker.exe"),
        _T("ShellExperienceHost.exe"),
        _T("SearchUI.exe"),
        _T("SearchIndexer.exe"),
        _T("WmiPrvSE.exe"),
        _T("Registry.exe"),
        _T("MsMpEng.exe"),
        _T("NisSrv.exe"),
        _T("audiodg.exe"),
        _T("wuauclt.exe"),
        _T("msdtc.exe"),
        _T("dasHost.exe"),
        _T("SgrmBroker.exe"),
        _T("SecurityHealthService.exe"),
        _T("SettingSyncHost.exe"),
        _T("SystemSettings.exe"),
        _T("WUDFHost.exe"),
        _T("WmiApSrv.exe"),
        _T("unsecapp.exe"),
        _T("LsaIso.exe"),
        _T("msiexec.exe"),
        _T("consent.exe"),
        _T("csrss.exe"),
        _T("LogonUI.exe"),
        _T("MemCompression"),
        _T("System"),
        _T("Idle"),
        _T("Secure System"),
        _T("Registry"),
        _T("Interrupts"),
        _T("DeviceGuard"),
        _T("WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe")
    };
    
    // 常见的后台进程名称（通常是各种服务和后台应用）
    static const LPCTSTR backgroundProcesses[] = {
        _T("sqlservr.exe"),
        _T("mysqld.exe"),
        _T("postgres.exe"),
        _T("httpd.exe"),
        _T("nginx.exe"),
        _T("apache.exe"),
        _T("tomcat.exe"),
        _T("java.exe"),
        _T("javaw.exe"),
        _T("node.exe"),
        _T("python.exe"),
        _T("ruby.exe"),
        _T("perl.exe"),
        _T("php.exe"),
        _T("mongod.exe"),
        _T("redis-server.exe"),
        _T("memcached.exe"),
        _T("elasticsearch.exe"),
        _T("splunkd.exe"),
        _T("zabbix_agentd.exe"),
        _T("telegraf.exe"),
        _T("influxd.exe"),
        _T("grafana-server.exe"),
        _T("prometheus.exe"),
        _T("AggregatorHost.exe"),
        _T("armsvc.exe"),
        _T("AsusLinkNear.exe"),
        _T("AsusLinkRemote.exe"),
        _T("AsusOptimization.exe"),
        _T("AsusOptimizationStartupTask.exe"),
        _T("AsusSystemAnalysis.exe"),
        _T("AsusSystemDiagnosis.exe"),
        _T("chrome.exe"),
        _T("firefox.exe"),
        _T("msedge.exe"),
        _T("OneDrive.exe"),
        _T("iCloudDrive.exe"),
        _T("DropboxUpdate.exe"),
        _T("GoogleDriveFS.exe"),
        _T("YourPhone.exe"),
        _T("Cortana.exe"),
        _T("Widgets.exe"),
        _T("WidgetService.exe"),
        _T("SynTPEnh.exe"),
        _T("igfxEM.exe"),
        _T("igfxHK.exe"),
        _T("igfxTray.exe"),
        _T("NvBackend.exe"),
        _T("nvtray.exe"),
        _T("RtkAudUService64.exe"),
        _T("RtkNGUI64.exe"),
        _T("IAStorIcon.exe"),
        _T("TCPSVCS.EXE"),
        _T("VSSVC.exe"),
        _T("WaaSMedicSvc.exe"),
        _T("WerFault.exe"),
        _T("WinStore.App.exe"),
        _T("WMIRegistrationService.exe"),
        _T("WUDFHost.exe"),
        _T("WmiApSrv.exe"),
        _T("unsecapp.exe"),
        _T("LsaIso.exe"),
        _T("msiexec.exe"),
        _T("consent.exe"),
        _T("csrss.exe"),
        _T("LogonUI.exe"),
        _T("MemCompression"),
        _T("System"),
        _T("Idle"),
        _T("Secure System"),
        _T("Registry"),
        _T("Interrupts"),
        _T("DeviceGuard"),
        _T("WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe")
    };
    
    // 首先检查是否是系统进程
    if (szProcessPath != NULL && szProcessPath[0] != _T('\0'))
    {
        // 检查路径是否包含Windows系统目录
        for (int i = 0; i < _countof(windowsPaths); i++)
        {
            if (_tcsstr(szProcessPath, windowsPaths[i]) != NULL)
            {
                return PROCESS_TYPE_WINDOWS;
            }
        }
    }
    
    // 检查进程名称是否匹配Windows系统进程
    for (int i = 0; i < _countof(windowsProcesses); i++)
    {
        if (_tcsicmp(szExeFile, windowsProcesses[i]) == 0)
        {
            return PROCESS_TYPE_WINDOWS;
        }
    }
    
    // 检查进程名称是否匹配后台进程
    for (int i = 0; i < _countof(backgroundProcesses); i++)
    {
        if (_tcsicmp(szExeFile, backgroundProcesses[i]) == 0)
        {
            return PROCESS_TYPE_BACKGROUND;
        }
    }
    
    // 检查特殊情况 - 某些进程虽然不在系统目录，但仍是系统进程
    if (szProcessPath != NULL && szProcessPath[0] != _T('\0'))
    {
        // 检查是否在Program Files目录下的Microsoft目录中
        if (_tcsstr(szProcessPath, _T("\\Program Files\\WindowsApps\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows Defender\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows Mail\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows Media Player\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows NT\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows Photo Viewer\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Windows Sidebar\\")) != NULL ||
            _tcsstr(szProcessPath, _T("\\Program Files\\Internet Explorer\\")) != NULL)
        {
            return PROCESS_TYPE_WINDOWS;
        }
    }
    
    // 默认为应用进程
    return PROCESS_TYPE_APP;
}

/*
函数：GetSelectedProcessID
功能：获取当前选中的进程ID
返回：选中进程的ID，如果没有选中则返回0
*/
DWORD CProcessMasterDlg::GetSelectedProcessID()
{
    // 检查是否有当前选中的列表
    if (m_processList.GetSafeHwnd() == NULL)
        return 0;

    // 获取选中项
    POSITION pos = m_processList.GetFirstSelectedItemPosition();
    if (pos == NULL)
        return 0;

    // 获取选中项的索引
    int nItem = m_processList.GetNextSelectedItem(pos);
    if (nItem < 0)
        return 0;

    // 获取进程ID（存储在列表项的lParam中）
    DWORD dwProcessID = (DWORD)m_processList.GetItemData(nItem);
    return dwProcessID;
}

/*
函数：EnableDebugPrivilege
功能：提升进程权限，以便能够访问系统进程
返回：成功返回TRUE，失败返回FALSE
*/
BOOL CProcessMasterDlg::EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    // 打开进程令牌
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        return FALSE;
    }

    // 获取特权值
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        CloseHandle(hToken);
        return FALSE;
    }

    // 设置特权
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    // 启用特权
    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
    {
        CloseHandle(hToken);
        return FALSE;
    }

    // 关闭句柄
    CloseHandle(hToken);
    return TRUE;
}

void CProcessMasterDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
    // 只在进程列表上显示右键菜单
    if (pWnd->GetSafeHwnd() == m_processList.GetSafeHwnd())
    {
        // 获取当前选中的进程ID
        DWORD dwProcessID = GetSelectedProcessID();
        if (dwProcessID == 0 || 
            dwProcessID == GROUP_HEADER_APP || 
            dwProcessID == GROUP_HEADER_BACKGROUND || 
            dwProcessID == GROUP_HEADER_WINDOWS)
        {
            // 未选中有效进程项，不显示菜单
            return;
        }

        // 创建弹出菜单
        CMenu menu;
        menu.LoadMenu(IDR_POPUP_MENU);
        CMenu* pPopup = menu.GetSubMenu(0);

        // 显示右键菜单
        pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 
                              point.x, point.y, this);
    }
}

void CProcessMasterDlg::OnEndProcess()
{
    // 调用原有的"结束进程"功能
    OnBtnEndProcess();
}

void CProcessMasterDlg::OnProcessDetail()
{
    // 调用原有的"进程详情"功能
    OnBtnProcessDetail();
}

/*
函数：OnBtnEndProcess
功能：处理结束进程按钮点击事件
说明：当用户点击结束进程按钮时，尝试终止选中的进程
*/
void CProcessMasterDlg::OnBtnEndProcess()
{
    // 获取当前选中的进程ID
    DWORD dwProcessID = GetSelectedProcessID();
    if (dwProcessID == 0)
    {
        // 没有选中任何进程
        TRACE("用户尝试结束进程，但未选择任何进程\n");
        
        MessageBox(_T("请先选择要结束的进程！"), _T("提示"), MB_OK | MB_ICONINFORMATION);
        return;
    }

    TRACE("用户尝试结束进程，进程ID: %d\n", dwProcessID);

    // 确认是否结束进程
    CString message;
    message.Format(_T("确定要结束进程ID为 %d 的进程吗？"), dwProcessID);
    if (MessageBox(message, _T("确认"), MB_YESNO | MB_ICONQUESTION) != IDYES)
    {
        // 用户取消操作
        TRACE("用户取消了结束进程操作\n");
        return;
    }

    // 打开进程
    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
    if (hProcess == NULL)
    {
        // 打开进程失败
        DWORD dwError = GetLastError();
        CString errorMessage;
        errorMessage.Format(_T("无法打开进程(错误码: %d)，可能是权限不足。"), dwError);
        
        TRACE("打开进程失败，进程ID: %d，错误码: %d\n", dwProcessID, dwError);
        
        MessageBox(errorMessage, _T("错误"), MB_OK | MB_ICONERROR);
        return;
    }

    // 尝试结束进程
    if (TerminateProcess(hProcess, 0))
    {
        // 结束进程成功
        TRACE("成功结束进程，进程ID: %d\n", dwProcessID);
        
        MessageBox(_T("进程已成功结束！"), _T("成功"), MB_OK | MB_ICONINFORMATION);
        
        // 刷新进程列表
        RefreshProcessLists();
    }
    else
    {
        // 结束进程失败
        DWORD dwError = GetLastError();
        CString errorMessage;
        errorMessage.Format(_T("结束进程失败(错误码: %d)。"), dwError);
        
        TRACE("结束进程失败，进程ID: %d，错误码: %d\n", dwProcessID, dwError);
        
        MessageBox(errorMessage, _T("错误"), MB_OK | MB_ICONERROR);
    }

    // 关闭进程句柄
    CloseHandle(hProcess);
}

/*
函数：OnBtnProcessDetail
功能：处理进程详情按钮点击事件
说明：当用户点击进程详情按钮时，显示选中进程的详细信息
*/
void CProcessMasterDlg::OnBtnProcessDetail()
{
    // 获取当前选中的进程ID
    DWORD dwProcessID = GetSelectedProcessID();
    if (dwProcessID == 0)
    {
        // 没有选中任何进程
        TRACE("用户尝试查看进程详情，但未选择任何进程\n");
        
        MessageBox(_T("请先选择要查看的进程！"), _T("提示"), MB_OK | MB_ICONINFORMATION);
        return;
    }

    TRACE("用户查看进程详情，进程ID: %d\n", dwProcessID);

    // 打开进程
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);
    if (hProcess == NULL)
    {
        // 打开进程失败
        DWORD dwError = GetLastError();
        CString errorMessage;
        errorMessage.Format(_T("无法打开进程(错误码: %d)，可能是权限不足。"), dwError);
        
        TRACE("打开进程失败，进程ID: %d，错误码: %d\n", dwProcessID, dwError);
        
        MessageBox(errorMessage, _T("错误"), MB_OK | MB_ICONERROR);
        return;
    }

    // 获取进程基本信息
    TCHAR szProcessName[MAX_PATH] = _T("未知");
    DWORD dwNeeded;
    
    // 获取进程名称（通过进程句柄获取模块信息）
    HMODULE hMod;
    if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwNeeded))
    {
        GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));
    }
    else
    {
        TRACE("获取进程模块信息失败，进程ID: %d，错误码: %d\n", dwProcessID, GetLastError());
    }

    // 获取进程内存信息
    PROCESS_MEMORY_COUNTERS pmc;
    ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS));
    pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
    if (!GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
    {
        TRACE("获取进程内存信息失败，进程ID: %d，错误码: %d\n", dwProcessID, GetLastError());
    }

    // 获取进程CPU使用率
    double cpuUsage = GetProcessCPUUsage(dwProcessID);

    // 构建详细信息字符串
    CString detailInfo;
    detailInfo.Format(
        _T("进程详细信息:\r\n\r\n")
        _T("进程名称: %s\r\n")
        _T("进程ID: %d\r\n")
        _T("CPU使用率: %.2f%%\r\n")
        _T("工作集大小: %.2f MB\r\n")
        _T("页面文件使用: %.2f MB\r\n")
        _T("峰值工作集: %.2f MB\r\n"),
        szProcessName,
        dwProcessID,
        cpuUsage,
        pmc.WorkingSetSize / 1024.0 / 1024.0,
        pmc.PagefileUsage / 1024.0 / 1024.0,
        pmc.PeakWorkingSetSize / 1024.0 / 1024.0
    );

    TRACE("显示进程详情，进程ID: %d，进程名称: %s，CPU使用率: %.2f%%，内存使用: %.2f MB\n", dwProcessID, szProcessName, cpuUsage, (pmc.WorkingSetSize / 1024.0 / 1024.0));

    // 显示详细信息
    MessageBox(detailInfo, _T("进程详情"), MB_OK | MB_ICONINFORMATION);

    // 关闭进程句柄
    CloseHandle(hProcess);
}

/*
函数：GetProcessCPUUsage
功能：获取指定进程的CPU使用率
参数： 
	dwProcessID - 进程ID
返回值： 
	CPU使用率（百分比）
说明： 
	从进程CPU使用率映射表中获取指定进程的CPU使用率
*/
double CProcessMasterDlg::GetProcessCPUUsage(DWORD dwProcessID)
{
    PROCESS_CPU_INFO cpuInfo;
    if (m_ProcessCPUInfo.Lookup(dwProcessID, cpuInfo))
    {
        return cpuInfo.cpuUsage;
    }
    
    return 0.0;
}

/*
函数：UpdateAllProcessCPUUsage
功能：更新所有进程的CPU使用率信息
说明： 
	1. 获取系统CPU时间和各进程CPU时间
	2. 计算时间差值，得出CPU使用率
	3. 更新进程CPU信息映射表
	4. 清理不存在的进程信息
	首次调用时只保存当前时间，不计算使用率
	需要至少两次调用才能得到有效的CPU使用率
*/
void CProcessMasterDlg::UpdateAllProcessCPUUsage()
{
	TRACE("开始更新CPU使用率信息\n");
	
	// 获取当前时间
	ULONGLONG currentTime = GetTickCount64();
	
	// 创建进程快照
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapshot == INVALID_HANDLE_VALUE)
	{
		TRACE("创建进程快照失败，错误码: %d\n", GetLastError());
		return;
	}
	
	// 遍历进程
	PROCESSENTRY32 pe32 = { 0 };
	pe32.dwSize = sizeof(PROCESSENTRY32);

	// 获取第一个进程信息
	if (!Process32First(hSnapshot, &pe32))
	{
		TRACE("获取第一个进程信息失败，错误码: %d\n", GetLastError());
		CloseHandle(hSnapshot);
		return;
	}
	
	int updatedCount = 0;
	do
	{
		// 打开进程
		HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
		if (hProcess)
		{
			// 获取进程CPU时间
			FILETIME ftCreation, ftExit, ftKernel, ftUser;
			if (GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser))
			{
				// 转换为ULARGE_INTEGER以便计算
				ULARGE_INTEGER kernelTime, userTime, currentCPUTime;
				kernelTime.LowPart = ftKernel.dwLowDateTime;
				kernelTime.HighPart = ftKernel.dwHighDateTime;
				userTime.LowPart = ftUser.dwLowDateTime;
				userTime.HighPart = ftUser.dwHighDateTime;
				
				// 计算总CPU时间
				currentCPUTime.QuadPart = kernelTime.QuadPart + userTime.QuadPart;
				
				// 查找进程之前的CPU信息
				PROCESS_CPU_INFO cpuInfo;
				if (m_ProcessCPUInfo.Lookup(pe32.th32ProcessID, cpuInfo))
				{
					// 计算CPU使用率
					ULONGLONG timeDiff = currentTime - cpuInfo.lastUpdateTime;
					if (timeDiff > 0)
					{
						ULONGLONG cpuTimeDiff = currentCPUTime.QuadPart - cpuInfo.lastCPUTime.QuadPart;
						cpuInfo.cpuUsage = (cpuTimeDiff * 100.0) / (timeDiff * 10000.0);
						
						// 限制CPU使用率范围在0-100之间
						if (cpuInfo.cpuUsage < 0) cpuInfo.cpuUsage = 0;
						if (cpuInfo.cpuUsage > 100) cpuInfo.cpuUsage = 100;
					}
				}
				else
				{
					// 新进程，初始化CPU信息
					cpuInfo.cpuUsage = 0;
				}
				
				// 更新CPU时间和更新时间
				cpuInfo.lastCPUTime.QuadPart = currentCPUTime.QuadPart;
				cpuInfo.lastUpdateTime = currentTime;
				cpuInfo.processID = pe32.th32ProcessID;
				
				// 更新到映射表
				m_ProcessCPUInfo.SetAt(pe32.th32ProcessID, cpuInfo);
				updatedCount++;
			}
			
			CloseHandle(hProcess);
		}
	} while (Process32Next(hSnapshot, &pe32));

	// 关闭进程快照
	CloseHandle(hSnapshot);
	
	// 清理不存在的进程
	POSITION pos = m_ProcessCPUInfo.GetStartPosition();
	int removedCount = 0;
	while (pos != NULL)
	{
		DWORD processID;
		PROCESS_CPU_INFO cpuInfo;
		m_ProcessCPUInfo.GetNextAssoc(pos, processID, cpuInfo);
		
		// 检查进程是否仍然存在
		HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processID);
		if (hProcess == NULL)
		{
			// 进程不存在，从映射表中移除
			m_ProcessCPUInfo.RemoveKey(processID);
			removedCount++;
			TRACE("移除不存在的进程CPU信息，进程ID: %d\n", processID);
		}
		else
		{
			CloseHandle(hProcess);
		}
	}
	
	TRACE("CPU使用率信息更新完成，更新 %d 个进程，移除 %d 个不存在的进程\n", updatedCount, removedCount);
}

void CProcessMasterDlg::OnClose()
{
    TRACE("应用程序关闭\n");
    
    // 销毁定时器
    KillTimer(1);
    
    // 恢复列表控件原始窗口过程
    if (m_pOldListProc && m_processList.GetSafeHwnd())
    {
        SetWindowLongPtr(m_processList.GetSafeHwnd(), GWLP_WNDPROC, (LONG_PTR)m_pOldListProc);
        TRACE("列表控件窗口过程已还原\n");
    }
    
    // 关闭日志系统
    /*CLogSystem::GetInstance().Close();*/
    
    CDialogEx::OnClose();
}
